package cn.micro.system.manage.common.security.custom;

import cn.micro.system.manage.common.component.RedisService;
import cn.micro.system.manage.common.constants.SecurityConstants;
import cn.micro.system.manage.common.result.Result;
import cn.micro.system.manage.common.utils.JwtHelper;
import cn.micro.system.manage.common.utils.ResponseUtil;
import com.alibaba.fastjson.JSON;
import com.github.xiaoymin.knife4j.core.util.StrUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;


@Slf4j
public class CustomLogoutSuccessHandler implements LogoutSuccessHandler {


    private final JwtHelper jwtHelper;


    private final RedisService redisService;

    public CustomLogoutSuccessHandler(JwtHelper jwtHelper, RedisService redisService) {
        this.jwtHelper = jwtHelper;
        this.redisService = redisService;
    }

    @Override
    public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        try {
            String token = ResponseUtil.resolveToken(httpServletRequest);
            if (StrUtil.isNotBlank(token)) {
                Claims claims = jwtHelper.getTokenClaims(token);
                String jti = claims.get("jti", String.class);
                Date expiration = claims.getExpiration();
                if (expiration != null) {
                    // 有过期时间，在token有效时间内存入黑名单，超出时间移除黑名单节省内存占用
                    long ttl = (expiration.getTime() - System.currentTimeMillis());
                    redisService.set(SecurityConstants.BLACK_TOKEN_CACHE_PREFIX + jti, null, ttl/1000);
                } else {
                    // 无过期时间，永久加入黑名单
                    redisService.set(SecurityConstants.BLACK_TOKEN_CACHE_PREFIX + jti, null);
                }
            }
            SecurityContextHolder.clearContext();
            ResponseUtil.out(httpServletResponse, Result.success().message("注销成功"));
        }catch (Exception e){
            e.printStackTrace();
            log.error("退出登录出现异常=======》{}",e.getMessage());
            ResponseUtil.out(httpServletResponse, Result.fail().message("注销失败"));
        }
    }
}
